﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing.Design;
using DesignPanel.Service;
using System.Drawing;
using System.Runtime.InteropServices;
using UIDesigner;

namespace DesignPanel
{
    public class DesignSurfaceEx : DesignSurface
    {
        private IDesignerHost m_theDesignerHost = null;
        ISelectionService m_theSelectionService = null;
        private Control m_theDesignContainer = null;
        private MenuService m_theMenuService = null;
        private DesignerOptionService m_theOptionService = null;
        private ControlListService m_theToolboxService = null;

        public event HookContextMenu OnContextMenu = null;
        public event ComponentEventHandler OnComponentAdded = null;
        public event ComponentEventHandler OnComponentRemoved = null;
        public event ComponentRenameEventHandler OnComponentRename = null;
        public event ComponentChangedEventHandler OnComponentChanged = null;
        public event EventHandler OnSelectionChanged = null;

        public DesignSurfaceEx() : base()
        {
            m_theDesignerHost = (IDesignerHost)ServiceContainer.GetService(typeof(IDesignerHost));
            // 提供右键菜单支持
            m_theMenuService = new MenuService(this);
            this.ServiceContainer.AddService(typeof(IMenuCommandService), m_theMenuService);
            // 属性设置
            m_theOptionService = new DesignerOptionServiceEx();
            this.ServiceContainer.AddService(typeof(DesignerOptionService), m_theOptionService);
            // Toolbox列表(拖拽支持)
            m_theToolboxService = new ControlListService();
            this.ServiceContainer.AddService(typeof(IToolboxService), m_theToolboxService);
            //
            m_theMenuService.OnContextMenu += new HookContextMenu(View_OnContextMenu);
            //
            IComponentChangeService obj = m_theDesignerHost as IComponentChangeService;
            if (obj != null)
            {
                obj.ComponentAdded += new ComponentEventHandler(View_ComponentAdded);
                obj.ComponentRemoved += new ComponentEventHandler(View_ComponentRemoved);
                obj.ComponentRename += new ComponentRenameEventHandler(View_ComponentRename);
                obj.ComponentChanged += new ComponentChangedEventHandler(View_ComponentChanged);
            }
            //
            m_theSelectionService = GetDesignService(typeof(ISelectionService)) as ISelectionService;
            if (m_theSelectionService != null)
            {
                m_theSelectionService.SelectionChanged += new EventHandler(View_ComponentSelectionChanged);
            }
        }

        public void CommandInvoke(CommandID id)
        {
            m_theMenuService.GlobalInvoke(id);
        }

        private void View_ComponentChanged(object sender, ComponentChangedEventArgs e)
        {
            if (OnComponentChanged != null)
            {
                OnComponentChanged(this, e);
            }
        }

        private void View_ComponentSelectionChanged(object sender, EventArgs e)
        {
            if (OnSelectionChanged != null)
            {
                OnSelectionChanged(this, e);
            }
        }

        private void View_ComponentRename(object sender, ComponentRenameEventArgs e)
        {
            if (OnComponentRename != null)
            {
                OnComponentRename(this, e);
            }
        }

        private void View_ComponentAdded(object sender, ComponentEventArgs e)
        {
            if (OnComponentAdded != null)
            {
                OnComponentAdded(this, e);
            }
        }

        private void View_ComponentRemoved(object sender, ComponentEventArgs e)
        {
            if (OnComponentRemoved != null)
            {
                OnComponentRemoved(this, e);
            }
        }

        private void View_OnContextMenu(Point ptMouse)
        {
            if (OnContextMenu != null)
            {
                Point ptClient = this.DesignContainer.PointToClient(ptMouse);
                OnContextMenu(ptClient);
            }
        }

        public IDesignerHost Host
        {
            get
            {
                return m_theDesignerHost;
            }
        }

        public Control RootComponent
        {
            get
            {
                if (m_theDesignerHost != null)
                {
                    return m_theDesignerHost.RootComponent as Control;
                }
                return null;
            }
        }

        public Control DesignContainer
        {
            get
            {
                if (m_theDesignContainer == null)
                {
                    m_theDesignContainer = this.View as Control;
                }
                return m_theDesignContainer;
            }
        }

        public ISelectionService Selections
        {
            get
            {
                return m_theSelectionService;
            }
        }

        public object GetDesignService(Type serviceType)
        {
            if (serviceType == typeof(IMenuCommandService))
            {
                return m_theMenuService;
            }
            else if (serviceType == typeof(IDesignerOptionService))
            {
                return m_theOptionService;
            }
            else if (serviceType == typeof(IToolboxService))
            {
                return m_theToolboxService;
            }
            return ServiceContainer.GetService(serviceType);
        }

        public void AddService(Type serviceType, object serviceInstance)
        {
            this.ServiceContainer.AddService(serviceType, serviceInstance);
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        internal class DesignerOptionServiceEx : DesignerOptionService
        {
            public DesignerOptionServiceEx() : base()
            {
            }

            protected override void PopulateOptionCollection(DesignerOptionCollection options)
            {
                if (null != options.Parent)
                {
                    return;
                }
                DesignerOptions ops = new DesignerOptions();
                ops.GridSize = new System.Drawing.Size(8, 8);
                ops.SnapToGrid = false;
                ops.ShowGrid = false;
                ops.ObjectBoundSmartTagAutoShow = true;
                ops.UseSnapLines = true;
                ops.UseSmartTags = false;
                DesignerOptionCollection obj = this.CreateOptionCollection(
                    options, "WindowsFormsDesigner", null);
                this.CreateOptionCollection(obj, "General", ops);
            }
        }
    }
}
